"""
自动路由发现模块
提供零配置的自动路由注册功能
"""
from fastapi import FastAPI
import os
import importlib.util
from pathlib import Path
from typing import List, Dict, Any
import sys


class AutoRouterDiscovery:
    """自动路由发现类"""
    
    def __init__(self):
        self.registered_routes: List[str] = []
        self.failed_routes: List[str] = []
        self.skipped_routes: List[str] = []
    
    def discover_and_register_routers(
        self, 
        app: FastAPI, 
        api_dir: str, 
        prefix: str = "/api/v1"
    ) -> Dict[str, Any]:
        """
        自动发现并注册路由
        
        Args:
            app: FastAPI应用实例
            api_dir: API目录路径
            prefix: 路由前缀
            
        Returns:
            Dict: 注册结果统计
        """
        print(f"🔍 开始自动发现路由，扫描目录: {api_dir}")
        
        # 重置状态
        self.registered_routes.clear()
        self.failed_routes.clear()
        self.skipped_routes.clear()
        
        api_path = Path(api_dir)
        
        if not api_path.exists():
            print(f"❌ API目录不存在: {api_dir}")
            return self._get_registration_summary()
        
        # 获取所有Python文件
        python_files = list(api_path.glob("*.py"))
        print(f"📁 发现 {len(python_files)} 个Python文件")
        
        for py_file in python_files:
            self._process_single_file(app, py_file, prefix)
        
        # 输出注册结果
        self._print_registration_summary()
        
        return self._get_registration_summary()
    
    def _process_single_file(self, app: FastAPI, py_file: Path, prefix: str):
        """处理单个Python文件"""
        if py_file.name.startswith("__"):
            print(f"⏭️  跳过系统文件: {py_file.name}")
            self.skipped_routes.append(py_file.name)
            return
        
        module_name = py_file.stem
        print(f"🔎 检查模块: {module_name}")
        
        try:
            # 动态导入模块
            module = self._import_module_from_file(py_file, module_name)
            
            if module is None:
                print(f"❌ 模块导入失败: {module_name}")
                self.failed_routes.append(module_name)
                return
            
            # 检查并注册router
            if hasattr(module, 'router'):
                router = getattr(module, 'router')
                
                # 验证router类型
                if self._is_valid_router(router):
                    # 注册路由
                    app.include_router(router, prefix=prefix)
                    self.registered_routes.append(module_name)
                    
                    # 获取路由信息
                    route_count = len(router.routes) if hasattr(router, 'routes') else 0
                    router_prefix = getattr(router, 'prefix', '') or ''
                    full_prefix = f"{prefix}{router_prefix}" if router_prefix else prefix
                    
                    print(f"✅ 路由注册成功: {module_name} -> {full_prefix} ({route_count} 个端点)")
                else:
                    print(f"⚠️  {module_name} 的router不是有效的APIRouter实例")
                    self.skipped_routes.append(module_name)
            else:
                print(f"⚠️  {module_name} 模块中未找到router属性")
                self.skipped_routes.append(module_name)
                
        except Exception as e:
            print(f"❌ 处理模块 {module_name} 时发生错误: {e}")
            self.failed_routes.append(module_name)
    
    def _import_module_from_file(self, py_file: Path, module_name: str):
        """从文件动态导入模块"""
        try:
            spec = importlib.util.spec_from_file_location(module_name, py_file)
            if spec is None or spec.loader is None:
                return None
                
            module = importlib.util.module_from_spec(spec)
            
            # 将模块添加到sys.modules中，避免重复导入
            sys.modules[module_name] = module
            
            spec.loader.exec_module(module)
            return module
            
        except Exception as e:
            print(f"❌ 导入模块 {module_name} 失败: {e}")
            return None
    
    def _is_valid_router(self, router) -> bool:
        """验证是否为有效的APIRouter实例"""
        try:
            # 检查是否有routes属性（APIRouter的特征）
            return hasattr(router, 'routes') and hasattr(router, 'include_router')
        except Exception:
            return False
    
    def _print_registration_summary(self):
        """打印注册结果摘要"""
        print(f"\n{'='*50}")
        print(f"🎉 自动路由发现完成")
        print(f"{'='*50}")
        
        if self.registered_routes:
            print(f"✅ 成功注册 ({len(self.registered_routes)} 个): {', '.join(self.registered_routes)}")
        
        if self.skipped_routes:
            print(f"⏭️  跳过模块 ({len(self.skipped_routes)} 个): {', '.join(self.skipped_routes)}")
        
        if self.failed_routes:
            print(f"❌ 注册失败 ({len(self.failed_routes)} 个): {', '.join(self.failed_routes)}")
        
        print(f"📊 总计扫描模块: {len(self.registered_routes) + len(self.skipped_routes) + len(self.failed_routes)} 个")
        print(f"{'='*50}")
    
    def _get_registration_summary(self) -> Dict[str, Any]:
        """获取注册结果摘要"""
        return {
            "registered": self.registered_routes,
            "skipped": self.skipped_routes,
            "failed": self.failed_routes,
            "summary": {
                "total_scanned": len(self.registered_routes) + len(self.skipped_routes) + len(self.failed_routes),
                "successful": len(self.registered_routes),
                "skipped": len(self.skipped_routes),
                "failed": len(self.failed_routes)
            }
        }
    
    def get_status(self) -> Dict[str, Any]:
        """获取当前状态"""
        return self._get_registration_summary()


# 全局自动路由发现实例
auto_router = AutoRouterDiscovery()


def auto_discover_routers(
    app: FastAPI, 
    api_dir: str, 
    prefix: str = "/api/v1"
) -> List[str]:
    """
    便捷函数：自动发现并注册路由
    
    Args:
        app: FastAPI应用实例
        api_dir: API目录路径
        prefix: 路由前缀
        
    Returns:
        List[str]: 成功注册的路由名称列表
    """
    result = auto_router.discover_and_register_routers(app, api_dir, prefix)
    return result["registered"]


def get_discovery_status() -> Dict[str, Any]:
    """获取路由发现状态"""
    return auto_router.get_status()